
#include "functions.h"


const float a_PIdiv180 = CV_PI/180.;



bool sortFunc(pair<string,float> &p1,pair<string,float> &p2)
{
	if( p1.second > p2.second)
		return true;
	else return false;
}

extern int  MAX_IMG_SIZE;

bool solveAffine(KeyPoint & key, featureRecord &fr,houghParam &resultParam)
{
	resultParam.delata_scale = std::log10f(key.size / fr.scale) / std::log10f(2);
	resultParam.delata_theta = key.angle - fr.theta ;
	float angle = resultParam.delata_theta * a_PIdiv180;
	float  sinTheta = std::sin(angle);
	float cosTheta = std::cos(angle);

	Mat affineTranform = (Mat_<float>(2,2)<<cosTheta,-sinTheta,sinTheta,cosTheta);
	affineTranform *= key.size / fr.scale;
	resultParam.delata_x = key.pt.x - fr.x * affineTranform.at<float>(0,0) - fr.y * affineTranform.at<float>(0,1) ;
	resultParam.delata_y = key.pt.y - fr.x * affineTranform.at<float>(1,0) - fr.y * affineTranform.at<float>(1,1) ;

	extern int  MAX_IMG_SIZE;
	resultParam.logoName = fr.logoName ;
	if(abs(resultParam.delata_x) > MAX_IMG_SIZE || abs(resultParam.delata_y) > MAX_IMG_SIZE)
		return false;
	return true;
}


extern float location_step  ;
extern float theta_step  ;
extern float scale_step  ;

extern int param_space_num;
extern int location_bin_num  ;
extern int theta_bin_num ;
extern int scale_bin_num ;

static inline bool sortFunction(int a,int b)
{
	return a>b;
}

int doHoughTransform(vector<houghParam> &parameters,int * param_space)
{
	if(parameters.size() < 2)
		return 0 ;

	memset(param_space,0,sizeof(int)*param_space_num);
	for(size_t i = 0 ; i != parameters.size() ; ++i)
	{
		int x_bin ,y_bin ,theta_bin,scale_bin;
		x_bin = cvRound(( parameters[i].delata_x + MAX_IMG_SIZE )/location_step );
		y_bin = cvRound( (parameters[i].delata_y + MAX_IMG_SIZE )/location_step);
		theta_bin = cvRound((parameters[i].delata_theta + 360)/theta_step);
		scale_bin = cvRound((parameters[i].delata_scale )/scale_step);

		for(int a = - 1 ; a  < 1 ; ++a)
			for(int b = -1 ; b < 1 ; ++b)
				for(int c = - 1 ; c < 1 ; ++c)
				{

					int temp_location = (x_bin + a ) * location_bin_num*theta_bin_num \
						+  ( y_bin + b ) *theta_bin_num\
						+  (  + c )  + theta_bin  ;
					if(temp_location >= param_space_num || temp_location < 0) continue;
					++param_space[temp_location] ;
				}

		//for(int a = - 1 ; a  < 1 ; ++a)
		//	for(int b = -1 ; b < 1 ; ++b)
		//		for(int c = - 1 ; c < 1 ; ++c)
		//			for(int d = - 1 ; d < 1 ; ++ d)
		//			{

		//				int temp_location = (x_bin + a ) * location_bin_num*scale_bin_num*theta_bin_num \
		//					+  ( y_bin + b ) *scale_bin_num*theta_bin_num\
		//					+  ( scale_bin + c ) * theta_bin_num + theta_bin +d ;
		//				if(temp_location >= param_space_num || temp_location < 0) continue;
		//				++param_space[temp_location] ;
		//			}
	}

	int score = 0 ;

	sort(param_space,param_space+param_space_num,sortFunction);
	score = param_space[0]  ;

	return score ;
}

//map<string,map<string,float>> parameters;
////map<string,vector<string>> logoImgNameTable;
//map<string,float> bias_term;
#ifdef USE_SVM
	string makeDecision(map<LogoImgInfo,float> &final_score,vector<string> &totalLogoImgName
		,vector<string> &logoNames,CvSVM &classifier)
#else	
	string makeDecision(map<LogoImgInfo,float> &final_score,vector<string> &totalLogoImgName
		,vector<string> &logoNames,CvRTrees &classifier)
#endif

{
	Mat trainData = Mat::zeros(1,totalLogoImgName.size(),CV_32FC1);
	//map<LogoImgInfo,float> & trainLogoScore = it_valImgIdx->second;
	map<LogoImgInfo,float>::iterator it = final_score.begin();

	float * temp_ptr = trainData.ptr<float>(0) ;
	for ( ; it != final_score.end() ; ++it)
	{
		FileList::iterator temp_it = find(totalLogoImgName.begin(),totalLogoImgName.end(),it->first.logoImgName);
		int colNum = temp_it - totalLogoImgName.begin();
		temp_ptr[colNum] = it->second ;
	}

	float predictedLabel = classifier.predict(trainData);
	return logoNames[(int)predictedLabel];
}

void imgResize(Mat &source , Mat &dst , int maxSize)
{
	if(source.rows < maxSize && source.cols < maxSize)
	{
		dst = Mat(source.rows,source.cols,source.type());
		dst = source;
		return ;
	}
	float scalar = 1.0;
	if(source.rows > source.cols)
		scalar = (float)maxSize / source.rows;
	else
		scalar = (float)maxSize / source.cols;

	dst = Mat(cvRound(source.rows * scalar), cvRound(source.cols * scalar),source.type());
	resize(source,dst,dst.size(),0,0,INTER_AREA);
}

